home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2008 February / PCWFEB08.iso / Software / Freeware / Miro 1.0 / Miro_Installer.exe / xulrunner / python / dl_daemon / subnetparse.py < prev   
Encoding:
Python Source  |  2007-11-12  |  5.0 KB  |  206 lines

  1. # Written by John Hoffman
  2. # see LICENSE.txt for license information
  3.  
  4. from bisect import bisect, insort
  5.  
  6. try:
  7.     True
  8. except:
  9.     True = 1
  10.     False = 0
  11.  
  12. hexbinmap = {
  13.     '0': '0000',
  14.     '1': '0001',
  15.     '2': '0010',
  16.     '3': '0011',
  17.     '4': '0100',
  18.     '5': '0101',
  19.     '6': '0110',
  20.     '7': '0111',
  21.     '8': '1000',
  22.     '9': '1001',
  23.     'a': '1010',
  24.     'b': '1011',
  25.     'c': '1100',
  26.     'd': '1101',
  27.     'e': '1110',
  28.     'f': '1111',
  29.     'x': '0000',
  30. }
  31.  
  32. chrbinmap = {}
  33. for n in xrange(256):
  34.     b = []
  35.     nn = n
  36.     for i in xrange(8):
  37.         if nn & 0x80:
  38.             b.append('1')
  39.         else:
  40.             b.append('0')
  41.         nn <<= 1
  42.     chrbinmap[n] = ''.join(b)
  43.  
  44.  
  45. def to_bitfield_ipv4(ip):
  46.     b = ''
  47.     for n in ip.split('.'):
  48.         b += chrbinmap[int(n)]
  49.     return b
  50.  
  51. def to_bitfield_ipv6(ip):
  52.     b = ''
  53.     doublecolon = False
  54.  
  55.     if ip == '':
  56.         raise ValueError, "bad address"
  57.     if ip == '::':      # boundary handling
  58.         ip = ''
  59.     elif ip[:2] == '::':
  60.         ip = ip[1:]
  61.     elif ip[0] == ':':
  62.         raise ValueError, "bad address"
  63.     elif ip[-2:] == '::':
  64.         ip = ip[:-1]
  65.     elif ip[-1] == ':':
  66.         raise ValueError, "bad address"
  67.     for n in ip.split(':'):
  68.         if n == '':     # double-colon
  69.             if doublecolon:
  70.                 raise ValueError, "bad address"
  71.             doublecolon = True
  72.             b += ':'
  73.             continue
  74.         if n.find('.') >= 0: # IPv4
  75.             n = to_bitfield_ipv4(n)
  76.             b += n + '0'*(32-len(n))
  77.             continue
  78.         n = ('x'*(4-len(n))) + n
  79.         for i in n:
  80.             b += hexbinmap[i]
  81.     if doublecolon:
  82.         pos = b.find(':')
  83.         b = b[:pos]+('0'*(129-len(b)))+b[pos+1:]
  84.     if len(b) != 128:   # always check size
  85.         raise ValueError, "bad address"
  86.     return b
  87.  
  88. ipv4addrmask = to_bitfield_ipv6('::ffff:0:0')[:96]
  89.  
  90. class IP_List:
  91.     def __init__(self):
  92.         self.ipv4list = []
  93.         self.ipv6list = []
  94.  
  95.     def __nonzero__(self):
  96.         return bool(self.ipv4list or self.ipv6list)
  97.  
  98.  
  99.     def append(self, ip, depth = 256):
  100.         if ip.find(':') < 0:        # IPv4
  101.             insort(self.ipv4list,to_bitfield_ipv4(ip)[:depth])
  102.         else:
  103.             b = to_bitfield_ipv6(ip)
  104.             if b.startswith(ipv4addrmask):
  105.                 insort(self.ipv4list,b[96:][:depth-96])
  106.             else:
  107.                 insort(self.ipv6list,b[:depth])
  108.  
  109.  
  110.     def includes(self, ip):
  111.         if not (self.ipv4list or self.ipv6list):
  112.             return False
  113.         if ip.find(':') < 0:        # IPv4
  114.             b = to_bitfield_ipv4(ip)
  115.         else:
  116.             b = to_bitfield_ipv6(ip)
  117.             if b.startswith(ipv4addrmask):
  118.                 b = b[96:]
  119.         if len(b) > 32:
  120.             l = self.ipv6list
  121.         else:
  122.             l = self.ipv4list
  123.         for map in l[bisect(l,b)-1:]:
  124.             if b.startswith(map):
  125.                 return True
  126.             if map > b:
  127.                 return False
  128.         return False
  129.  
  130.  
  131.     def read_fieldlist(self, file):   # reads a list from a file in the format 'ip/len <whatever>'
  132.         try:
  133.             f = open(file, 'r')
  134.             lines = f.readlines()
  135.             f.close()
  136.         except:
  137.             print '*** ERROR *** could not read IP range file'
  138.             return
  139.         for line in lines:
  140.             line = line.strip().expandtabs()
  141.             if not line or line[0] == '#':
  142.                 continue
  143.             try:
  144.                 line, garbage = line.split(' ',1)
  145.             except:
  146.                 pass
  147.             try:
  148.                 line, garbage = line.split('#',1)
  149.             except:
  150.                 pass
  151.             try:
  152.                 ip, depth = line.split('/')
  153.             except:
  154.                 ip = line
  155.                 depth = None
  156.             try:
  157.                 if depth is not None:                
  158.                     depth = int(depth)
  159.                 self.append(ip,depth)
  160.             except:
  161.                 print '*** WARNING *** could not parse IP range: '+line
  162.  
  163.  
  164.     def set_intranet_addresses(self):
  165.         self.append('127.0.0.1',8)
  166.         self.append('10.0.0.0',8)
  167.         self.append('172.16.0.0',12)
  168.         self.append('192.168.0.0',16)
  169.         self.append('169.254.0.0',16)
  170.         self.append('::1')
  171.         self.append('fe80::',16)
  172.         self.append('fec0::',16)
  173.  
  174.     def set_ipv4_addresses(self):
  175.         self.append('::ffff:0:0',96)
  176.  
  177. def to_ipv4(ip):
  178.     if ip.find(':') < 0:
  179.         raise ValueError, "not an IPv6 address"
  180.     ip = to_bitfield_ipv6(ip)
  181.     if not ip.startswith(ipv4addrmask):
  182.         raise ValueError, "not convertible to IPv4"
  183.     ip = ip[-32:]
  184.     x = ''
  185.     for i in range(4):
  186.         x += str(int(ip[:8],2))
  187.         if i < 3:
  188.             x += '.'
  189.         ip = ip[8:]
  190.     return x
  191.  
  192. def is_ipv4(ip):
  193.     return ip.find(':') < 0
  194.  
  195. def is_valid_ip(ip):
  196.     try:
  197.         if is_ipv4(ip):
  198.             a = ip.split('.')
  199.             assert len(a) == 4
  200.             for i in a:
  201.                 chr(int(i))
  202.             return True
  203.         to_bitfield_ipv6(ip)
  204.         return True
  205.     except:
  206.         return False